#!/usr/bin/env python
# -*- coding: utf-8 -*-
##
#  Project: Kelindo - Unsupervised Music Organizer  
#  Author: Nicola Bicocchi <nicola.bicocchi@gmail.com>, Nicolo' Torreggiani <nicolo.torreggiani@gmail.com>, Gianluca Puglia <gianluca.puglia@gmail.com>, Matteo Senardi <pualien@gmail.com>
#  Copyright: 2013 Nicola Bicocchi, Nicolo' Torreggiani, Gianluca Puglia, Matteo Senardi
#  License: GPL-2+
#  This program is free software; you can redistribute it and/or modify it
#  under the terms of the GNU General Public License as published by the Free
#  Software Foundation; either version 2 of the License, or (at your option)
#  any later version.
# 
#  This program is distributed in the hope that it will be useful, but WITHOUT
#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
#  more details.
# 
# On Debian GNU/Linux systems, the full text of the GNU General Public License
# can be found in the file /usr/share/common-licenses/GPL-2.
##

import glob
import os
import shutil
import sys

from distutils.core import setup, Command
from distutils.dep_util import newer
from distutils.command.build_scripts import build_scripts as distutils_build_scripts
from distutils.spawn import find_executable

from gdist import GDistribution
from gdist.clean import clean as gdist_clean

PACKAGES = ("core qltk").split()

MIN_PYTHON_VER = (2,6)
MIN_PYTHON_VER_STR = ".".join(map(str,MIN_PYTHON_VER))

class clean(gdist_clean):
    def run(self):
        gdist_clean.run(self)

        def should_remove(filename):
            if (filename.lower()[-4:] in [".pyc", ".pyo",] or
                filename.endswith("~") or
                (filename.startswith("#") and filename.endswith("#"))):
                return True
            else:
                return False
        for pathname, dirs, files in os.walk(os.path.dirname(__file__)):
            for filename in filter(should_remove, files):
                try: os.unlink(os.path.join(pathname, filename))
                except EnvironmentError, err:
                    print str(err)

        for base in ["coverage", "build", "dist"]:
            path = os.path.join(os.path.dirname(__file__), base)
            if os.path.isdir(path):
                shutil.rmtree(path)


class build_scripts(distutils_build_scripts):
    description = "copy scripts to build directory"

    def run(self):
        self.mkpath(self.build_dir)
        for script in self.scripts:
            newpath = os.path.join(self.build_dir, os.path.basename(script))
            if newpath.lower().endswith(".py"):
                newpath = newpath[:-3]
            if newer(script, newpath) or self.force:
                self.copy_file(script, newpath)


class check(Command):
    description = "check installation requirements"
    user_options = []

    NAME = "Kelindo"

    def initialize_options(self):
        pass

    def finalize_options(self):
        pass

    def run(self):
        print "Checking Python version >= %s:" % MIN_PYTHON_VER_STR,
        if sys.version_info < MIN_PYTHON_VER:
            raise SystemExit("%s requires at least Python %s. "
                             "(http://www.python.org)"
                             % (self.NAME, ".".join(map(str,MIN_PYTHON_VER))))
        else:
            print "found"

        print "Checking for Python-PyGTK >= 2.16:",
        try:
            import pygtk
            pygtk.require('2.0')
            import gtk
            if gtk.pygtk_version < (2, 16) or gtk.gtk_version < (2, 16):
                raise ImportError
        except ImportError:
            raise SystemExit("not found\n%s requires PyGTK 2.10. " % self.NAME)
        else: 
            print "found"

        print "Checking for Python-Mutagen >= 1.11:",
        try:
            import mutagen
            if mutagen.version < (1, 11):
                raise ImportError
        except ImportError:
            raise SystemExit("not found\n%s requires Mutagen 1.11.\n" % self.NAME)
        else: print "found"
        
        print "Checking for Python-Requests >= 0.8:",
        try:
            import requests
            if tuple(map(int, requests.__version__.split('.'))) < (0, 8, 0):
                raise ImportError
        except ImportError:
            raise SystemExit("not found\n%s requires Requests 0.8.2.\n" % self.NAME)
        else: print "found"
        
        print "Checking for Sox:",
        if not find_executable("sox"):
            raise SystemExit("not found\n%s requires Sox 14.3.2.\n" %
                self.NAME)
        else: print "found"
        
#        TODO
#        print "Checking for Sox-fmt-mp3:",
#        if not distutils.ccompiler.  find_library_file(["/usr/lib", "/usr/local/lib"], "libsox_fmt_mp3.so"):
#            raise SystemExit("not found\n%s requires Sox-fmt-mp3 14.3.2.\n" %
#                self.NAME)
#        else: print "found"

        print """\n\
Your system meets the installation requirements. Run %(setup)s install to
install it.""" % dict(setup=sys.argv[0])

def recursive_include(dir, pre, ext):
    all = []
    old_dir = os.getcwd()
    os.chdir(dir)
    for path, dirs, files in os.walk(pre):
        for file in files:
            if file.split('.')[-1] in ext:
                all.append(os.path.join(path, file))
    os.chdir(old_dir)
    return all

def recursive_include_py2exe(dir, pre, ext):
    all = []
    dir = os.path.join(dir, pre)
    for path, dirs, files in os.walk(dir):
        all_path = []
        for file in files:
            if file.split('.')[-1] in ext:
                all_path.append(os.path.join(path, file))
        if all_path: all.append((path, all_path))
    return all

if __name__ == "__main__":
    os.chdir(os.path.dirname(os.path.abspath(__file__)))

    from kelindo import const
    cmd_classes = {"check": check, 'clean': clean, "build_scripts": build_scripts}
    setup_kwargs = {
        'distclass': GDistribution,
        'cmdclass': cmd_classes,
        'name': "kelindo",
        'version': const.VERSION,
        'url': "http://code.google.com/p/kelindo/",
        'description': "unsupervised music tagger and organizer",
        'author': "Nicola Bicocchi",
        'author_email': "nicola.bicocchi@gmail.com",
        'maintainer': "Nicola Bicocchi",
        'license': "GNU GPL v2",
        'packages': ["kelindo"] + map("kelindo.".__add__, PACKAGES),
        'package_data': {"kelindo": recursive_include("kelindo", "images", ("png"))},
        'scripts': ["gkelindo.py", "kelindo.py",],
        #'po_directory': "po",
        #'po_package': "kelindo",
        #'shortcuts': ["kelindo.desktop",],
        #'man_pages': ["man/kelindo.1",],
        }
        
    if os.name == 'nt':
        # (probably) necessary to get the right DLLs pulled in by py2exe
        import pygst
        pygst.require('0.10')
        from os.path import join

        # taken from http://www.py2exe.org/index.cgi/win32com.shell
        # ModuleFinder can't handle runtime changes to __path__, but win32com uses them
        try:
            # py2exe 0.6.4 introduced a replacement modulefinder.
            # This means we have to add package paths there, not to the built-in
            # one.  If this new modulefinder gets integrated into Python, then
            # we might be able to revert this some day.
            # if this doesn't work, try import modulefinder
            try:
                import py2exe.mf as modulefinder
            except ImportError:
                import modulefinder
            import win32com
            for p in win32com.__path__[1:]:
                modulefinder.AddPackagePath("win32com", p)
            for extra in ["win32com.shell"]: #,"win32com.mapi"
                __import__(extra)
                m = sys.modules[extra]
                for p in m.__path__[1:]:
                    modulefinder.AddPackagePath(extra, p)
        except ImportError:
            # no build path setup, no worries.
            pass

        data_files = [('', ['COPYING'])] +  recursive_include_py2exe(
            "kelindo", "images", ("png",))

        for type in ["playorder", "songsmenu", "editing", "events", "gstreamer"]:
            data_files.append((join('kelindo', 'html', type),
                glob.glob(join('..', 'plugins', type, '*.py'))))

        setup_kwargs.update({
            'data_files': data_files,
            'windows': [
                {
                    "script": "gkelindo.py",
                    "icon_resources": [(0,
                       join('..', 'win_installer', 'quodlibet.ico'))]
                },
                # workaround icon not working under Vista/7
                # exe resource identifiers get incremented and start at 0.
                # and 0 doesn't seem to be valid.
                {
                    "script": "kelindo.py",
                    "icon_resources": [(0,
                       join('..', 'win_installer', 'quodlibet.ico'))]
                },
            ],
            'options': {
                'py2exe': {
                    'packages': ('encodings, feedparser, quodlibet, '
                                 'HTMLParser, gtk, glib, gobject, '
                                 'musicbrainz2, shelve, json, pyHook'),
                    'includes': ('cairo, pango, pangocairo, atk, gio, '
                                 'pygst, gst, quodlibet.player.gstbe, '
                                 'CDDB'),
                    'excludes': ('ssl_', 'doctest', 'pdb', 'unittest',
                                 'difflib', 'inspect'),
                    'skip_archive': True,
                    'dist_dir': 'dist\\bin'
                }
            }
        })
    setup(**setup_kwargs)

